Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BuiltinRule -> FunctionApplyRule #1085

Merged
merged 2 commits into from
Sep 17, 2024
Merged

BuiltinRule -> FunctionApplyRule #1085

merged 2 commits into from
Sep 17, 2024

Conversation

rocky
Copy link
Member

@rocky rocky commented Sep 16, 2024

The name Builtin is vague, since there are things that are "builtin" (like variables and symbols) that are not functions.

Furthermore, BuiltinRule handles functions added by Mathics3 modules.

The name Builtin is vague, since there are things that are
"builtin" (like variables and symbols) that are not functions.

Furthermore, BuiltinRule handles functions added by Mathics3 modules.
@rocky rocky requested a review from mmatera September 16, 2024 02:07
@mmatera
Copy link
Contributor

mmatera commented Sep 16, 2024

Here we can take the chance to mention in the documentation (at least in the docstring) is that when a BuiltinRule (FunctionApplyRule) is applied, the "match" status of the rule depends on the return value of the applied function.

For example, suppose that we try to apply the "standard" F[x_]->x^2 to the expression F[2]: Then, the pattern "matches" with the expression, Blank[x] is replaced by 2 and the new expression 2^2 is obtained. At this point, the evaluation method stops looking for other rules to be applied over F[2].

On the other hand, suppose that we define a FunctionApplyRule that associates F[x_] with the function

def eval_f(x, evaluation):
   "F[x_]"
    if x>3:
        return Expression(SymbolPower, x, Integer2)
   return None

Then, if we apply the rule to F[2], the function is evaluated with None as its result. Then, in the evaluation loop, we get the same effect as the pattern didn't match with the expression: the loop continues then with the next rule associated to F.

Why do we have this behavior?

Because sometimes, the cost of deciding if the rule match is similar to the cost of evaluating the function. Suppose for example a rule

F[x_/;(G[x]>0)]:=G[x]

with G[x] a computationally expensive function. To decide if G[x] is larger than 0, we need to evaluate it, and once we have evaluated it, just need to return its value.

Also, this allows us to handle several rules in the same function, without relying on our very slow pattern-matching routines, in particular, for some "critical" low-level tasks like building lists in iterators, processing arithmetic expressions, plotting functions, or evaluating derivatives and integrals.

@rocky
Copy link
Member Author

rocky commented Sep 16, 2024

Good! I will mention this both as a docstring and add it to the developers guide.

Copy link
Contributor

@mmatera mmatera left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@rocky rocky merged commit 6c02434 into master Sep 17, 2024
11 checks passed
@rocky rocky deleted the rename-BuiltinRule branch September 17, 2024 00:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants